package com.ke.rule.base;

import org.slf4j.Logger;

/**
 * service method step
 * 
 * @author guyu
 */
public abstract class ServiceMethodStep {

  protected final DecisionBasedServiceMethod<?> method;
  protected final Logger logger;

  protected ServiceMethodStep(DecisionBasedServiceMethod<?> method, Logger logger) {
    super();
    this.method = method;
    this.logger = logger;
  }
  
  /**
   * execute this step
   */
  public ValidationException.Builder shift() {
    String brkdwnName = method.getCurrentStepType().name();
    String brkdwnExtension = String.format("%s@%s", method.getClass().getName(), Integer.toHexString(method.hashCode()));
    CallLatency.begin(brkdwnName, brkdwnExtension, CallBreakdown.GROUP_METHOD);
    
    String traceId = SnippetsTrace.begin();
    if (logger.isDebugEnabled()) {
      logger.debug("{} go...", method.getCurrentStepType());
    }
    
    ValidationException.Builder builder = null;
    boolean isDone = false;
    try {
      if (MethodStepType.DetermineFeasibility == method.getCurrentStepType()) {
        method.prepareStudyData();
      }
      builder = go();
      isDone = true;
    } finally {
      if (logger.isDebugEnabled()) {
        logger.debug("{} {}, duration {} ms", method.getCurrentStepType(), isDone ? "done" : "failed", SnippetsTrace.end(traceId));
      }
      CallLatency.end(brkdwnName, brkdwnExtension);
    }
    return builder;
  }
  
  protected abstract ValidationException.Builder go();
}
